#include "sock.hpp"
#include <vector>
#include <unordered_map>
class Chat
{
public:
    Chat(int type)
    {
        _data = _socket.Creat(type);
        _socket.Bind();
        if (type & SOCK_STREAM)
            _socket.Listen();
    }
    void Start()
    {
        pthread_create(&_tid, nullptr, Read, this);
        while (true)
            Write();
    }
    static void *Read(void *arg)
    {
        pthread_detach(pthread_self());
        Chat *ptr = (Chat *)arg;
        while (true)
        {
            sockaddr_in *client_ptr = new sockaddr_in;
            socklen_t len = sizeof(*client_ptr);
            ssize_t s = recvfrom(ptr->_data._sock, ptr->_midbuffer, _BUFFER_NUN - 1, 0, (sockaddr *)client_ptr, &len);
            ptr->_midbuffer[s] = '\0';
            if (!ptr->_map.empty())
            {
                for (const auto &e : ptr->_map)
                {
                    if (e.first->sin_port == client_ptr->sin_port)
                    {
                        delete client_ptr;
                        break;
                    }
                    ptr->_map.emplace(std::make_pair(client_ptr, len));
                }
            }
            else
                ptr->_map.emplace(std::make_pair(client_ptr, len));

        }
        return nullptr;
    }
    void Write()
    {
        if (strlen(_midbuffer) == 0)
            return;
        if (!_map.empty())
        {
            for (const auto &e : _map)
            {
                socklen_t len = sizeof(*(e.first));
                sendto(_data._sock, _midbuffer, _BUFFER_NUN - 1, 0, (sockaddr *)(e.first), len);
            }
            memset(_midbuffer, 0, _BUFFER_NUN);
        }
    }

private:
    std::vector<char *> _buffer;
    char _midbuffer[_BUFFER_NUN];
    Data _data;
    Sock _socket;
    pthread_t _tid;
    std::unordered_map<sockaddr_in *, int> _map;
};